﻿using AutoMapper;
using CleanArchitecture.Infrastructure.AutoMapper;
using CleanArchitecture.Infrastructure.Entities;
using CleanArchitecture.Infrastructure.Entities.AdminUsers;
using CleanArchitecture.Infrastructure.Entities.Business;
using CleanArchitecture.Infrastructure.Entities.Settings;
using CleanArchitecture.Infrastructure.Entities.System.DataDic;
using CleanArchitecture.Infrastructure.Entities.System.Notice;
using CleanArchitecture.Infrastructure.Entities.SystemModules;
using CleanArchitecture.Infrastructure.Models.AdminUsers;
using CleanArchitecture.Infrastructure.Models.Business.Advertises;
using CleanArchitecture.Infrastructure.Models.Business.Blog;
using CleanArchitecture.Infrastructure.Models.Business.Columns;
using CleanArchitecture.Infrastructure.Models.Business.Comments;
using CleanArchitecture.Infrastructure.Models.Business.FileUpload;
using CleanArchitecture.Infrastructure.Models.Business.News;
using CleanArchitecture.Infrastructure.Models.SystemManage;

namespace CleanArchitecture.Infrastructure.Models
{
    #region Value Formatter
    public class EnumFormatter : IValueConverter<EntityEnumConfig.YesorNo, bool>
    {
        public bool Convert(EntityEnumConfig.YesorNo sourceMember, ResolutionContext context)
        {
            return sourceMember == EntityEnumConfig.YesorNo.YES;    
        }
    }
    public class BoolFormatter : IValueConverter<bool, EntityEnumConfig.YesorNo>
    {
        public EntityEnumConfig.YesorNo Convert(bool sourceMember, ResolutionContext context)
        {
            return sourceMember ? EntityEnumConfig.YesorNo.YES 
                                : EntityEnumConfig.YesorNo.No;
        }
    }
    #endregion Value Formatter
    public class AutoMapperConfiguration : Profile, IOrderedMapperProfile
    {
        #region Ctor
        public AutoMapperConfiguration()
        {
            CreateAdminUserMaps();
            CreateAdminRoleMaps();
            CreateSystemDataDicButtonMaps();
            CreateSystemDataDicTreeMaps();
            CreateSystemModuleMaps();
            CreateSystemNoticeMaps();
            CreateColumnMaps();
            CreateNewsMaps();
            CreateBlogMaps();
            CreateFileUploadMaps();
            CreateAdvertiseMaps();
            CreateCommentMaps();
        }
        #endregion

        #region Model Entity Config
        protected virtual void CreateAdminUserMaps()
        {
            CreateMap<AdminUser, AdminUserModel>()
                .ForMember(model => model.LastLoginTime, options => options.Ignore())
                .ForMember(model => model.FaceImageUrl, options => options.Ignore())
                .ForMember(model => model.IsAdmin, options => options.Ignore())
                .ForMember(model => model.LastLoginIpAddress, options => options.Ignore())
                .ForMember(model => model.NewPassword, options => options.Ignore())
                .ForMember(model => model.OldPassword, options => options.Ignore())
                .ForMember(model => model.PasswordStrongLevel, options => options.Ignore())
                .ForMember(model => model.RoleNames, options => options.Ignore())
                .ForMember(model => model.SelectedRoleIds, options => options.Ignore())
                .ForMember(model => model.AvailableAdminRoles, options => options.Ignore());
            CreateMap<AdminUserModel, AdminUser>()
                .ForMember(entity => entity.LastLoginTimeUtc, options => options.Ignore())
                .ForMember(entity => entity.CreatedOnTimeUtc, options => options.Ignore())
                .ForMember(entity => entity.FailedLoginAttempts, options => options.Ignore())
                //.ForMember(entity => entity.AdminuserAdminroleMappings, options => options.Ignore())
                .ForMember(entity => entity.LastLoginIp, options => options.Ignore());
        }
        protected virtual void CreateAdminRoleMaps()
        {
            CreateMap<AdminRole, AdminRoleModel>()
                .ForMember(model => model.OranizeName, options => options.Ignore());
            CreateMap<AdminRoleModel, AdminRole>()
                .ForMember(entity => entity.AdminroleSystemModuleMappings, options => options.Ignore())
                .ForMember(entity => entity.AdminroleBusinessColumnMappings, options => options.Ignore())
                .ForMember(entity => entity.Organize, options => options.Ignore())
                .ForMember(entity => entity.CreatedOnTimeUtc, options => options.Ignore());
        }
        protected virtual void CreateSystemDataDicTreeMaps()
        {
            CreateMap<SystemDataDicTree, SystemDataDicTreeItemModel>();
            CreateMap<SystemDataDicTreeItemModel, SystemDataDicTree>();
        }
        protected virtual void CreateSystemDataDicButtonMaps()
        {
            CreateMap<SystemDataDicButton, SystemDataDicButtonModel>()
                .ForMember(model => model.AvailableButtonTypes, options => options.Ignore())
                .ForMember(model => model.ButtonTypeDisplay, options => options.Ignore());
                
            CreateMap<SystemDataDicButtonModel, SystemDataDicButton>()
                .ForMember(entity => entity.CreatedOnTimeUtc, options => options.Ignore())
                .ForMember(entity => entity.FKSystemDataDicTreeId, options => options.Ignore())
                .ForMember(entity => entity.BelongTreeNode, options => options.Ignore());
        }
        protected virtual void CreateSystemModuleMaps()
        {
            CreateMap<SystemModule, SystemModuleModel>()
                .ForMember(model => model.AvailableModuleTypes, options => options.Ignore())
                .ForMember(model => model.ParentIdDisplay, options => options.Ignore())
                .ForMember(model => model.ModuleTypeDisplay, options => options.Ignore())
                .ForMember(model => model.ModuleAuthorizedButtons, options => options.Ignore())
                .ForMember(model => model.ModuleAssignedButtonsDic, options => options.Ignore())
                .ForMember(model => model.ModuleAssignedButtonNames, options => options.Ignore());

            CreateMap<SystemModuleModel, SystemModule>()
                .ForMember(entity => entity.CreatedOnTimeUtc, options => options.Ignore())
                .ForMember(entity => entity.ModuleAssignedButtonIds, options => options.Ignore())
                .ForMember(entity => entity.AdminroleSystemModuleMappings, options => options.Ignore());
        }

        protected virtual void CreateSystemNoticeMaps()
        {
            CreateMap<SystemNotice, SystemNoticeModel>()
                .ForMember(model => model.Title, options => options.MapFrom(entity => entity.NoticeTitle))
                .ForMember(model => model.Text, options => options.MapFrom(entity => entity.NoticeText))
                .ForMember(model => model.CreatedTime, options => options.Ignore());

            CreateMap<SystemNoticeModel, SystemNotice>()
                .ForMember(entity => entity.NoticeTitle, options => options.MapFrom(entity => entity.Title))
                .ForMember(entity => entity.NoticeText, options => options.MapFrom(entity => entity.Text))
                .ForMember(entity => entity.CreatedOnTimeUtc, options => options.Ignore())
                .ForMember(entity => entity.IsActive, options => options.Ignore());
        }
        /// <summary>
        /// Create news maps 
        /// </summary>
        protected virtual void CreateNewsMaps()
        {
            //CreateMap<NewsComment, NewsCommentModel>()
            //    .ForMember(model => model.CustomerInfo, options => options.Ignore())
            //    .ForMember(model => model.CreatedOn, options => options.Ignore())
            //    .ForMember(model => model.CommentText, options => options.Ignore())
            //    .ForMember(model => model.NewsItemTitle, options => options.Ignore())
            //    .ForMember(model => model.StoreName, options => options.Ignore());
            //CreateMap<NewsCommentModel, NewsComment>()
            //    .ForMember(entity => entity.NewsItem, options => options.Ignore())
            //    .ForMember(entity => entity.CommentTitle, options => options.Ignore())
            //    .ForMember(entity => entity.CommentText, options => options.Ignore())
            //    .ForMember(entity => entity.CreatedOnUtc, options => options.Ignore())
            //    .ForMember(entity => entity.Customer, options => options.Ignore())
            //    .ForMember(entity => entity.NewsItemId, options => options.Ignore())
            //    .ForMember(entity => entity.CustomerId, options => options.Ignore())
            //    .ForMember(entity => entity.StoreId, options => options.Ignore())
            //    .ForMember(entity => entity.Store, options => options.Ignore());

            CreateMap<NewsItem, NewsItemModel>()
               .ForMember(model => model.AllowComments, options => options.ConvertUsing(new EnumFormatter()))
               .ForMember(model => model.IsRecommend, options => options.ConvertUsing(new EnumFormatter()))
               .ForMember(model => model.IsActive, options => options.ConvertUsing(new EnumFormatter()))
               .ForMember(model => model.ImageIds, options => options.Ignore())
               .ForMember(model => model.ImageUrls, options => options.Ignore())
               .ForMember(model => model.AudioIds, options => options.Ignore())
               .ForMember(model => model.AudioUrls, options => options.Ignore())
               .ForMember(model => model.VideoIds, options => options.Ignore())
               .ForMember(model => model.VideoUrls, options => options.Ignore())
               .ForMember(model => model.FileIds, options => options.Ignore())
               .ForMember(model => model.FileUrls, options => options.Ignore())
               .ForMember(model => model.FileTitles, options => options.Ignore())
               .ForMember(model => model.CreatedOnTime, options => options.Ignore())
               .ForMember(model => model.UpdatedOnTime, options => options.Ignore())
               .ForMember(model => model.StartTaskTime, options => options.Ignore())
               .ForMember(model => model.FKColumnId, options => options.MapFrom(entity => entity.FKColumnId));
            CreateMap<NewsItemModel, NewsItem>()
                .ForMember(entity => entity.StartTaskTimeUtc, options => options.Ignore())
                .ForMember(entity => entity.CreatedOnTimeUtc, options => options.Ignore())
                .ForMember(entity => entity.UpdatedOnTimeUtc, options => options.Ignore())
                .ForMember(entity => entity.IsActive, options => options.ConvertUsing(new BoolFormatter()))
                .ForMember(entity => entity.IsRecommend, options => options.ConvertUsing(new BoolFormatter()))
                .ForMember(entity => entity.AllowComments, options => options.ConvertUsing(new BoolFormatter()))
                .ForMember(entity => entity.FKColumnId, options => options.MapFrom(model => model.FKColumnId));

            CreateMap<NewsSettings, NewsSettingsModel>();
            CreateMap<NewsSettingsModel, NewsSettings>();
        }
        /// <summary>
        /// Create blog maps 
        /// </summary>
        protected virtual void CreateBlogMaps()
        {
            CreateMap<BlogItem, BlogItemModel>()
                .ForMember(model => model.AllowComments, options => options.ConvertUsing(new EnumFormatter()))
                .ForMember(model => model.IsRecommend, options => options.ConvertUsing(new EnumFormatter()))
                .ForMember(model => model.IsActive, options => options.ConvertUsing(new EnumFormatter()))
                .ForMember(model => model.ImageIds, options => options.Ignore())
                .ForMember(model => model.ImageUrls, options => options.Ignore())
                .ForMember(model => model.AudioIds, options => options.Ignore())
                .ForMember(model => model.AudioUrls, options => options.Ignore())
                .ForMember(model => model.VideoIds, options => options.Ignore())
                .ForMember(model => model.VideoUrls, options => options.Ignore())
                .ForMember(model => model.FileIds, options => options.Ignore())
                .ForMember(model => model.FileUrls, options => options.Ignore())
                .ForMember(model => model.CreatedOnTime, options => options.Ignore())
                .ForMember(model => model.UpdatedOnTime, options => options.Ignore())
                .ForMember(model => model.StartTaskTime, options => options.Ignore())
                .ForMember(model => model.FKColumnId, options => options.MapFrom(entity => entity.FKColumnId));
            CreateMap<BlogItemModel, BlogItem>()
                .ForMember(entity => entity.StartTaskTimeUtc, options => options.Ignore())
                .ForMember(entity => entity.CreatedOnTimeUtc, options => options.Ignore())
                .ForMember(entity => entity.UpdatedOnTimeUtc, options => options.Ignore())
                .ForMember(entity => entity.IsActive, options => options.ConvertUsing(new BoolFormatter()))
                .ForMember(entity => entity.IsRecommend, options => options.ConvertUsing(new BoolFormatter()))
                .ForMember(entity => entity.AllowComments, options => options.ConvertUsing(new BoolFormatter()))
                .ForMember(entity => entity.FKColumnId, options => options.MapFrom(model => model.FKColumnId));

            CreateMap<BlogSettings, BlogSettingsModel>();
            CreateMap<BlogSettingsModel, BlogSettings>();
        }
        protected virtual void CreateColumnMaps()
        {
            CreateMap<Column, ColumnItemModel>()
                .ForMember(model => model.LanguageId, options => options.MapFrom(entity => entity.FKLanguageId))
                .ForMember(model => model.Name, options => options.MapFrom(entity => entity.DisplayName))
                .ForMember(model => model.LanguageName, options => options.Ignore())
                .ForMember(model => model.LanguageCulture, options => options.Ignore())
                .ForMember(model => model.LanguageCode, options => options.Ignore())
                .ForMember(model => model.ParentId, options => options.MapFrom(entity => entity.PID));
            CreateMap<ColumnItemModel, Column>()
                .ForMember(entity => entity.UpdatedOnTimeUtc, options => options.Ignore())
                .ForMember(entity => entity.CreatedOnTimeUtc, options => options.Ignore())
                .ForMember(entity => entity.AdminroleBusinessColumnMappings, options => options.Ignore())
                .ForMember(entity => entity.DisplayName, options => options.MapFrom(model => model.Name))
                .ForMember(entity => entity.FKLanguageId, options => options.MapFrom(model => model.LanguageId))
                .ForMember(entity => entity.PID, options => options.MapFrom(model => model.ParentId));
        }

        protected virtual void CreateFileUploadMaps()
        {
            CreateMap<FileUpload, FileItemModel>()
                .ForMember(model => model.VirtualUrl, options => options.Ignore());
            CreateMap<FileItemModel, FileUpload>()
                .ForMember(entity => entity.IsNew, options => options.Ignore())
                .ForMember(entity => entity.FileBinary, options => options.Ignore())
                .ForMember(entity => entity.VirtualPath, options => options.Ignore())
                .ForMember(entity => entity.UpdatedOnTimeUtc, options => options.Ignore());
        }

        protected virtual void CreateAdvertiseMaps()
        {
            CreateMap<Advertise, AdvertiseBannerModel>()
                .ForMember(model => model.StartTime, options => options.Ignore())
                .ForMember(model => model.EndTime, options => options.Ignore());
            CreateMap<AdvertiseBannerModel, Advertise>()
                .ForMember(entity => entity.CreatedOnTimeUtc, options => options.Ignore())
                .ForMember(entity => entity.IsActive, options => options.Ignore())
                .ForMember(entity => entity.StartTimeUtc, options => options.Ignore())
                .ForMember(entity => entity.EndTimeUtc, options => options.Ignore());
        }
        protected virtual void CreateCommentMaps()
        {
            CreateMap<Comment, CommentItemModel>()
                .ForMember(model => model.CommentIsResponsed, options => options.ConvertUsing(new EnumFormatter()))
                .ForMember(model => model.ImageIds, options => options.MapFrom(entity => entity.ImgIds))
                .ForMember(model => model.CreatedTime, options => options.Ignore());
            CreateMap<CommentItemModel, Comment>()
                .ForMember(entity => entity.CreatedOnTimeUtc, options => options.Ignore())
                .ForMember(entity => entity.IsActive, options => options.Ignore())
                .ForMember(entity => entity.CommentIsResponsed, options => options.ConvertUsing(new BoolFormatter()))
                .ForMember(entity => entity.ImgIds, options => options.MapFrom(model => model.ImageIds));
        }
        #endregion

        public int Order => 0;
    }
}
